{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "60d1a836f542"
   },
   "outputs": [],
   "source": [
    "# Copyright 2021 The Cirq Developers\n",
    "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "# you may not use this file except in compliance with the License.\n",
    "# You may obtain a copy of the License at\n",
    "#\n",
    "# https://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software\n",
    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "# See the License for the specific language governing permissions and\n",
    "# limitations under the License."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "058c886e7d6d"
   },
   "source": [
    "# State Histograms\n",
    "State Histograms are useful to visualize the output of running a quantum circuit. For details on how to create and run your own quantum circuits, please see [Cirq basics](../start/basics.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "78cd9ffef102"
   },
   "source": [
    "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://quantumai.google/cirq/simulate/state_histograms\"><img src=\"https://quantumai.google/site-assets/images/buttons/quantumai_logo_1x.png\" />View on QuantumAI</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/quantumlib/Cirq/blob/main/docs/simulate/state_histograms.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/colab_logo_1x.png\" />Run in Google Colab</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://github.com/quantumlib/Cirq/blob/main/docs/simulate/state_histograms.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/github_logo_1x.png\" />View source on GitHub</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a href=\"https://storage.googleapis.com/tensorflow_docs/Cirq/docs/simulate/state_histograms.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/download_icon_1x.png\" />Download notebook</a>\n",
    "  </td>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "614826b3777a"
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    import cirq\n",
    "except ImportError:\n",
    "    print(\"installing cirq...\")\n",
    "    !pip install --quiet cirq\n",
    "    print(\"installed cirq.\")\n",
    "    import cirq\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "acebe6240f0b"
   },
   "source": [
    "### Basic usage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "c1c6adeeb0e1"
   },
   "outputs": [],
   "source": [
    "q = cirq.LineQubit.range(4)\n",
    "circuit = cirq.Circuit([cirq.H.on_each(*q), cirq.measure(*q)])\n",
    "result = cirq.Simulator().run(circuit, repetitions=100)\n",
    "_ = cirq.plot_state_histogram(result, plt.subplot())\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "da358e505449"
   },
   "source": [
    "### Plotting circuits with sparse output\n",
    "If the results have sparse output, you can use the `result.histogram` to compute the histogram and plot only states that have non-zero sample count. For example:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3bed4f1d4222"
   },
   "source": [
    "#### Default plot\n",
    "The default call to `cirq.plot_state_histogram` would plot all possible output states (including 0's). This can get messy, especially if the output is sparse."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "789958187e7d"
   },
   "outputs": [],
   "source": [
    "q = cirq.LineQubit.range(6)\n",
    "circuit = cirq.Circuit(\n",
    "    [\n",
    "        cirq.H(q[0]),\n",
    "        [cirq.CNOT(q[0], q[i]) for i in range(1, 6, 1)],\n",
    "        cirq.measure(*q, key='measure_all'),\n",
    "    ]\n",
    ")\n",
    "result = cirq.Simulator().run(circuit, repetitions=100)\n",
    "_ = cirq.plot_state_histogram(result, plt.subplot())\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "d7c05a17460b"
   },
   "source": [
    "#### Sparse plots\n",
    "To plot only non-zero entries in the histogram, you can first compute a histogram using `result.histogram()` and pass its result to `cirq.plot_state_histogram`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "2405b58effd0"
   },
   "outputs": [],
   "source": [
    "histogram = result.histogram(key='measure_all')\n",
    "_ = cirq.plot_state_histogram(histogram, plt.subplot())\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "7dab59bc0b62"
   },
   "source": [
    "### Histogram for processed results.\n",
    "`result.histogram()` also allows you to pass a `fold_func` parameter that can be used to process the sampled measurement results and convert to a countable value to generate a histogram.\n",
    "\n",
    "As an example, suppose you want to plot a histogram of the parity of the number of times a `1` occurs in a measurement result. We can do this using `fold_func` as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "64d8a54596bc"
   },
   "outputs": [],
   "source": [
    "def count_ones(bits):\n",
    "    return 'even' if sum(bits) % 2 == 0 else 'odd'\n",
    "\n",
    "\n",
    "q = cirq.LineQubit.range(6)\n",
    "# Uniform superposition over all 2 ** 6 states.\n",
    "circuit = cirq.Circuit([cirq.H.on_each(*q), cirq.measure(*q, key='measure_all')])\n",
    "result = cirq.Simulator().run(circuit, repetitions=100)\n",
    "# Create a customized histogram by processing the measurement results using `fold_func`.\n",
    "custom_histogram = result.histogram(key='measure_all', fold_func=count_ones)\n",
    "# Plot the custom histogram using cirq.plot_state_histogram\n",
    "_ = cirq.plot_state_histogram(custom_histogram, plt.subplot())\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ac5483d0a913"
   },
   "source": [
    "### Modifying plot properties\n",
    "You can pass additional arguments to the `cirq.plot_state_histogram` method to modify plot properties like `title`, `xlabel`, `ylabel` and `tick_label`. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "16aa0365af6a"
   },
   "outputs": [],
   "source": [
    "def binary_labels(num_qubits):\n",
    "    return [bin(x)[2:].zfill(num_qubits) for x in range(2**num_qubits)]\n",
    "\n",
    "\n",
    "q = cirq.LineQubit.range(3)\n",
    "circuit = cirq.Circuit([cirq.H.on_each(*q), cirq.measure(*q)])\n",
    "result = cirq.Simulator().run(circuit, repetitions=100)\n",
    "_ = cirq.plot_state_histogram(\n",
    "    result,\n",
    "    plt.subplot(),\n",
    "    title='Custom Plot Title',\n",
    "    xlabel='Custom X-Axis Label',\n",
    "    ylabel='Custom Y-Axis Label',\n",
    "    tick_label=binary_labels(3),\n",
    ")\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "state_histograms.ipynb",
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
